//! 集群模块适配器
//! 
//! 该模块将nacos-cluster模块集成到nacos-server中

use std::sync::Arc;
use tracing::{info, warn};
use nacos_cluster::NodeHealth;

use nacos_cluster::{ClusterManager, DataSyncManager, ConsistencyManager, ClusterConfigManager};
use nacos_network::grpc::service::{ClusterService, DataSyncService};
use nacos_core::{ClusterNode, NacosError, NodeRole};

/// 集群服务实现
pub struct ServerClusterService {
    cluster_manager: Arc<ClusterManager>,
}

impl ServerClusterService {
    pub fn new(cluster_manager: Arc<ClusterManager>) -> Self {
        Self { cluster_manager }
    }
}

#[async_trait::async_trait]
impl ClusterService for ServerClusterService {
    async fn get_cluster_info(&self) -> Result<String, tonic::Status> {
        let nodes = self.cluster_manager.get_all_nodes().await;
        let info = serde_json::json!({
            "nodes": nodes,
            "size": nodes.len()
        });
        
        serde_json::to_string(&info)
            .map_err(|e| tonic::Status::internal(e.to_string()))
    }

    async fn add_node_from_info(&self, node_info: String) -> Result<(), tonic::Status> {
        let node: nacos_cluster::node::ClusterNodeInfo = serde_json::from_str(&node_info)
            .map_err(|e| tonic::Status::invalid_argument(e.to_string()))?;
        
        self.cluster_manager.add_node(node).await
            .map_err(|e| tonic::Status::internal(e.to_string()))
    }

    async fn remove_node(&self, node_id: &str) -> Result<(), tonic::Status> {
        self.cluster_manager.remove_node(node_id).await
            .map_err(|e| tonic::Status::internal(e.to_string()))
    }

    async fn is_healthy(&self) -> Result<bool, tonic::Status> {
        let nodes = self.cluster_manager.get_healthy_nodes().await;
        Ok(!nodes.is_empty())
    }
}

/// 数据同步服务实现
pub struct ServerDataSyncService {
    data_sync_manager: Arc<DataSyncManager>,
}

impl ServerDataSyncService {
    pub fn new(data_sync_manager: Arc<DataSyncManager>) -> Self {
        Self { data_sync_manager }
    }
}

#[async_trait::async_trait]
impl DataSyncService for ServerDataSyncService {
    async fn handle_sync_message(
        &self,
        sync_type: String,
        from_node: String,
        data: String,
        version: u64,
        timestamp: u64,
    ) -> Result<String, tonic::Status> {
        // 简化的数据同步处理
        let response = serde_json::json!({
            "type": sync_type,
            "from": from_node,
            "data": data,
            "version": version,
            "timestamp": timestamp,
            "status": "processed"
        });

        serde_json::to_string(&response)
            .map_err(|e| tonic::Status::internal(e.to_string()))
    }
}

/// 集群集成管理器
pub struct ClusterIntegrationManager {
    pub cluster_manager: Arc<ClusterManager>,
    pub data_sync_manager: Arc<DataSyncManager>,
    pub consistency_manager: Arc<ConsistencyManager>,
    pub config_manager: Arc<ClusterConfigManager>,
    cluster_service: Arc<ServerClusterService>,
    data_sync_service: Arc<ServerDataSyncService>,
}

impl ClusterIntegrationManager {
    pub fn new(
        cluster_manager: Arc<ClusterManager>,
        data_sync_manager: Arc<DataSyncManager>,
        consistency_manager: Arc<ConsistencyManager>,
        config_manager: Arc<ClusterConfigManager>,
    ) -> Self {
        let cluster_service = Arc::new(ServerClusterService::new(cluster_manager.clone()));
        let data_sync_service = Arc::new(ServerDataSyncService::new(data_sync_manager.clone()));

        Self {
            cluster_manager,
            data_sync_manager,
            consistency_manager,
            config_manager,
            cluster_service,
            data_sync_service,
        }
    }

    /// 获取集群服务
    pub fn cluster_service(&self,
    ) -> Arc<dyn nacos_network::grpc::service::ClusterService> {
        self.cluster_service.clone()
    }

    /// 获取数据同步服务
    pub fn data_sync_service(&self,
    ) -> Arc<dyn nacos_network::grpc::service::DataSyncService> {
        self.data_sync_service.clone()
    }

    /// 启动集群服务
    pub async fn start(
        &self,
    ) -> Result<(), NacosError> {
        info!("启动集群集成管理器...");

        // 启动集群管理器
        self.cluster_manager.check_cluster_health().await
            .map_err(|e| NacosError::Cluster(e.to_string()))?;

        info!("集群集成管理器启动完成");
        Ok(())
    }

    /// 停止集群服务
    pub async fn stop(
        &self,
    ) -> Result<(), NacosError> {
        info!("停止集群集成管理器...");

        // 集群管理器使用shutdown
        self.cluster_manager.shutdown().await
            .map_err(|e| NacosError::Cluster(e.to_string()))?;

        info!("集群集成管理器停止完成");
        Ok(())
    }

    /// 获取集群状态
    pub async fn get_cluster_status(&self,
    ) -> Result<ClusterStatus, NacosError> {
        let nodes = self.cluster_manager.get_all_nodes().await;
        let healthy_nodes = self.cluster_manager.get_healthy_nodes().await;
        
        Ok(ClusterStatus {
            cluster_id: "default".to_string(),
            leader_id: None,
            member_count: nodes.len(),
            healthy_nodes: healthy_nodes.len(),
            total_nodes: nodes.len(),
            is_leader: false,
        })
    }

    /// 获取集群节点
    pub async fn get_cluster_nodes(&self) -> Result<Vec<ClusterNode>, NacosError> {
        let nodes = self.cluster_manager.get_all_nodes().await;
        Ok(nodes.into_iter().map(|node| node.to_cluster_node()).collect())
    }

    /// 添加集群节点
    pub async fn add_cluster_node(
        &self,
        node: ClusterNode,
    ) -> Result<(), NacosError> {
        let node_info = nacos_cluster::node::ClusterNodeInfo {
            node_id: node.node_id.clone(),
            ip: node.ip.clone(),
            port: node.port,
            state: node.state,
            role: NodeRole::Follower,
            weight: 1,
            last_heartbeat: chrono::Utc::now(),
            join_time: node.join_time,
            metadata: node.metadata,
            health: NodeHealth::Healthy,
        };
        self.cluster_manager.add_node(node_info).await
            .map_err(|e| NacosError::Cluster(e.to_string()))
    }

    /// 移除集群节点
    pub async fn remove_cluster_node(
        &self,
        node_id: &str,
    ) -> Result<(), NacosError> {
        self.cluster_manager.remove_node(node_id).await
            .map_err(|e| NacosError::Cluster(e.to_string()))
    }

    /// 同步数据到集群
    pub async fn sync_data_to_cluster(
        &self,
        _data_type: &str,
        _data: &str,
    ) -> Result<(), NacosError> {
        // 简化的数据同步实现
        Ok(())
    }

    /// 获取集群配置
    pub async fn get_cluster_config(&self,
    ) -> Result<nacos_cluster::ClusterConfig, NacosError> {
        // 返回默认配置
        Ok(nacos_cluster::ClusterConfig::default())
    }

    /// 更新集群配置
    pub async fn update_cluster_config(
        &self,
        _config: nacos_cluster::ClusterConfig,
    ) -> Result<(), NacosError> {
        // 简化的配置更新
        Ok(())
    }
}

/// 集群状态信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ClusterStatus {
    pub cluster_id: String,
    pub leader_id: Option<String>,
    pub member_count: usize,
    pub healthy_nodes: usize,
    pub total_nodes: usize,
    pub is_leader: bool,
}

impl Default for ClusterStatus {
    fn default() -> Self {
        Self {
            cluster_id: String::new(),
            leader_id: None,
            member_count: 0,
            healthy_nodes: 0,
            total_nodes: 0,
            is_leader: false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use nacos_cluster::ClusterConfig;

    #[tokio::test]
    async fn test_cluster_service_adapters() {
        let cluster_config = ClusterConfig::default();
        let cluster_manager = Arc::new(ClusterManager::new(cluster_config.clone()));
        let data_sync_manager = Arc::new(DataSyncManager::new(cluster_manager.clone()));
        let consistency_manager = Arc::new(ConsistencyManager::new(
            cluster_manager.clone(),
            data_sync_manager.clone(),
        ));
        let config_manager = Arc::new(ClusterConfigManager::new(cluster_config));

        let integration = ClusterIntegrationManager::new(
            cluster_manager,
            data_sync_manager,
            consistency_manager,
            config_manager,
        );

        let cluster_service = integration.cluster_service();
        let data_sync_service = integration.data_sync_service();

        // 测试服务创建
        assert_eq!(cluster_service.name(), "ServerClusterService");
        assert_eq!(data_sync_service.name(), "ServerDataSyncService");
    }
}